package cn.lg.soar.system.biz.modules.auth.client;

import cn.lg.soar.common.util.AssertUtil;
import cn.lg.soar.core.annotations.ApiClient;
import cn.lg.soar.system.api.constant.ModuleConst;
import cn.lg.soar.system.api.model.*;
import cn.lg.soar.system.api.service.IUserApi;
import cn.lg.soar.system.biz.modules.auth.entity.AccountBind;
import cn.lg.soar.system.biz.modules.auth.entity.User;
import cn.lg.soar.system.biz.modules.auth.entity.UserPostRel;
import cn.lg.soar.system.biz.modules.auth.entity.UserRoleRel;
import cn.lg.soar.system.biz.modules.auth.service.IAccountBindService;
import cn.lg.soar.system.biz.modules.auth.service.IUserService;
import cn.lg.soar.system.biz.modules.auth.service.UserPostRelService;
import cn.lg.soar.system.biz.modules.auth.service.UserRoleRelService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.v3.oas.annotations.Hidden;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author luguoxiang
 * @date 2022/1/3
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
@Hidden
@ApiClient("boot")
@RestController
@RequestMapping(ModuleConst.CLIENT_PATH + "/user")
public class UserApiClient implements IUserApi {

    @Autowired
    private IUserService service;
    @Autowired
    private IAccountBindService accountBindService;
    @Autowired
    private UserRoleRelService userRoleRelService;
    @Autowired
    private UserPostRelService userOrgService;

    @GetMapping("getById")
    @Override
    public UserQueryDTO getById(@RequestParam(name = "userId") Long userId) {
        return toQueryDTO(service.getById(userId));
    }

    @GetMapping("listByIds")
    @Override
    public List<UserQueryDTO> listByIds(@RequestParam(name = "ids") Collection<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return Collections.emptyList();
        }
        return service.listByIds(ids).stream().map(this::toQueryDTO).collect(Collectors.toList());
    }

    @PostMapping("create")
    @Override
    public Long create(@RequestBody UserCreateDTO dto) {
        return service.create(dto);
    }

    @PostMapping("update")
    @Override
    public void update(@RequestBody UserUpdateDTO dto) {
        User user = toEntity(dto);
        AssertUtil.isTrue(service.updateById(user), "更新用户失败");
    }

    @GetMapping("getUserCurrentAllRoleIds")
    @Override
    public List<Long> getUserCurrentAllRoleIds(@RequestParam(name = "userId") Long userId) {
        return service.getUserCurrentAllRoleIds(userId);
    }

    @GetMapping("isSuperAdministrator/username")
    @Override
    public boolean isSuperAdministrator(@RequestParam(name = "username") String username) {
        return service.isSuperAdministrator(username);
    }

    @GetMapping("isSuperAdministrator/userId")
    @Override
    public boolean isSuperAdministrator(@RequestParam(name = "userId") Long userId) {
        return service.isSuperAdministrator(userId);
    }

    @GetMapping("idsByRoleId")
    @Override
    public List<Long> idsByRoleId(@RequestParam(name = "roleIds") Collection<Long> roleIds) {
        return userRoleRelService.listObjs(
                Wrappers.<UserRoleRel>lambdaQuery()
                        .select(UserRoleRel::getUserId)
                        .in(UserRoleRel::getRoleId, roleIds),
                x -> Long.parseLong(x.toString())
        );
    }

    @GetMapping("idsByOrgId")
    @Override
    public List<Long> idsByOrgId(@RequestParam(name = "orgIds") Collection<Long> orgIds) {
        return userOrgService.listObjs(
                Wrappers.<UserPostRel>lambdaQuery()
                        .select(UserPostRel::getUserId)
                        .in(UserPostRel::getOrgId, orgIds),
                x -> Long.parseLong(x.toString())
        );
    }

    @GetMapping("idsByPostId")
    @Override
    public List<Long> idsByPostId(@RequestParam(name = "postIds") Collection<Long> postIds) {
        return userOrgService.listObjs(
                Wrappers.<UserPostRel>lambdaQuery()
                        .select(UserPostRel::getUserId)
                        .in(UserPostRel::getPostId, postIds),
                x -> Long.parseLong(x.toString())
        );
    }

    @GetMapping("idsByOrgAndRole")
    @Override
    public List<Long> idsByOrgAndRole(@RequestParam(name = "orgId") Long orgId, @RequestParam(name = "roleId") Long roleId) {
        return service.idsByOrgAndRole(orgId, roleId);
    }

    @PostMapping("binding")
    @Override
    public void binding(@RequestBody UserBindDTO dto) {
        accountBindService.binding(dto.getAccountType(), dto.getAccount(), dto.getUserId());
    }

    @GetMapping("getByAccount")
    @Override
    public UserQueryDTO getByAccount(@RequestParam(name = "accountType") Integer accountType, @RequestParam(name = "account") String account) {
        User user = accountBindService.getUser(accountType, account);
        return toQueryDTO(user);
    }

    @GetMapping("userAccountList")
    @Override
    public List<AuthAccountBind> userAccountList(Long userId) {
        List<AccountBind> accounts = accountBindService.listByUserId(userId);
        return accounts.stream().map(x -> {
            AuthAccountBind authAccountBind = new AuthAccountBind();
            authAccountBind.setAccountType(x.getAccountType());
            authAccountBind.setAccount(x.getAccount());
            authAccountBind.setRemark(x.getRemark());
            return authAccountBind;
        }).collect(Collectors.toList());
    }

    private UserQueryDTO toQueryDTO(User user) {
        UserQueryDTO dto = new UserQueryDTO();
        dto.setId(user.getId());
        dto.setUsername(user.getUsername());
        dto.setAvatar(user.getAvatar());
        dto.setNickname(user.getNickname());
        dto.setStatus(user.getStatus());
        dto.setUserType(user.getUserType());
        dto.setLoginCount(user.getLoginCount());
        dto.setLastLoginDate(user.getLastLoginDate());
        dto.setCurrentTenantId(user.getCurrentTenantId());
        dto.setPwdErrorCount(user.getPwdErrorCount());
        return dto;
    }

    private User toEntity(UserUpdateDTO dto) {
        User user = new User();
        user.setId(dto.getId());
        user.setUsername(dto.getUsername());
        user.setNickname(dto.getNickname());
        user.setPassword(dto.getPassword());
        user.setAvatar(dto.getAvatar());
        user.setUserType(dto.getUserType());
        return user;
    }
}
